{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "5eb60008",
   "metadata": {},
   "source": [
    "# 生成式预训练语言模型：理论与实战\n",
    "深蓝学院 课程 \n",
    "课程链接：https://www.shenlanxueyuan.com/course/620\n",
    "\n",
    "作者 **黄佳**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "d3216379",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "词汇表： ['Boss', 'is', 'Niuzong', 'Teacher', 'Xiaoxue', 'Kage', 'Xiaobing', 'Mazong', 'Student']\n",
      "词汇到索引的字典： {'Boss': 0, 'is': 1, 'Niuzong': 2, 'Teacher': 3, 'Xiaoxue': 4, 'Kage': 5, 'Xiaobing': 6, 'Mazong': 7, 'Student': 8}\n",
      "索引到词汇的字典： {0: 'Boss', 1: 'is', 2: 'Niuzong', 3: 'Teacher', 4: 'Xiaoxue', 5: 'Kage', 6: 'Xiaobing', 7: 'Mazong', 8: 'Student'}\n",
      "词汇表大小： 9\n"
     ]
    }
   ],
   "source": [
    "# 定义一个句子列表，后面会用这些句子来训练CBOW和Skip-Gram模型\n",
    "sentences = [\"Kage is Teacher\", \"Mazong is Boss\", \"Niuzong is Boss\",\n",
    "             \"Xiaobing is Student\", \"Xiaoxue is Student\",]\n",
    "# 将所有句子连接在一起，然后用空格分隔成词汇\n",
    "words = ' '.join(sentences).split()\n",
    "# 构建词汇表，去除重复的词\n",
    "word_list = list(set(words))\n",
    "# 创建一个字典，将每个词汇映射到一个唯一的索引\n",
    "word_to_idx = {word: idx for idx, word in enumerate(word_list)}\n",
    "# 创建一个字典，将每个索引映射到对应的词汇\n",
    "idx_to_word = {idx: word for idx, word in enumerate(word_list)}\n",
    "voc_size = len(word_list) # 计算词汇表的大小\n",
    "print(\"词汇表：\", word_list) # 输出词汇表\n",
    "print(\"词汇到索引的字典：\", word_to_idx) # 输出词汇到索引的字典\n",
    "print(\"索引到词汇的字典：\", idx_to_word) # 输出索引到词汇的字典\n",
    "print(\"词汇表大小：\", voc_size) # 输出词汇表大小"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "de8f4ae7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Skip-Gram数据样例（未编码）： [('is', 'Kage'), ('Teacher', 'Kage'), ('Kage', 'is'), ('Teacher', 'is'), ('Kage', 'Teacher'), ('is', 'Teacher'), ('is', 'Mazong'), ('Boss', 'Mazong'), ('Mazong', 'is'), ('Boss', 'is'), ('Mazong', 'Boss'), ('is', 'Boss'), ('is', 'Niuzong'), ('Boss', 'Niuzong'), ('Niuzong', 'is'), ('Boss', 'is'), ('Niuzong', 'Boss'), ('is', 'Boss'), ('is', 'Xiaobing'), ('Student', 'Xiaobing'), ('Xiaobing', 'is'), ('Student', 'is'), ('Xiaobing', 'Student'), ('is', 'Student'), ('is', 'Xiaoxue'), ('Student', 'Xiaoxue'), ('Xiaoxue', 'is'), ('Student', 'is'), ('Xiaoxue', 'Student'), ('is', 'Student')]\n"
     ]
    }
   ],
   "source": [
    "# 生成Skip-Gram训练数据\n",
    "def create_skipgram_dataset(sentences, window_size=2):\n",
    "    data = []\n",
    "    for sentence in sentences:\n",
    "        sentence = sentence.split()  # 将句子分割成单词列表\n",
    "        for idx, word in enumerate(sentence):  # 遍历单词及其索引\n",
    "            # 获取相邻的单词，将当前单词前后各N个单词作为相邻单词\n",
    "            for neighbor in sentence[max(idx - window_size, 0): \n",
    "                        min(idx + window_size + 1, len(sentence))]:\n",
    "                if neighbor != word:  # 排除当前单词本身\n",
    "                    # 将相邻单词与当前单词作为一组训练数据\n",
    "                    data.append((neighbor, word))\n",
    "    return data\n",
    "# 使用函数创建Skip-Gram训练数据\n",
    "skipgram_data = create_skipgram_dataset(sentences)\n",
    "# 打印未编码的Skip-Gram数据样例（前三个）\n",
    "print(\"Skip-Gram数据样例（未编码）：\", skipgram_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "72158e33",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "One-Hot编码前的单词： Teacher\n",
      "One-Hot编码后的向量： tensor([0., 0., 0., 1., 0., 0., 0., 0., 0.])\n",
      "Skip-Gram数据样例（已编码）： [(tensor([0., 1., 0., 0., 0., 0., 0., 0., 0.]), 5), (tensor([0., 0., 0., 1., 0., 0., 0., 0., 0.]), 5), (tensor([0., 0., 0., 0., 0., 1., 0., 0., 0.]), 1)]\n"
     ]
    }
   ],
   "source": [
    "# 定义One-Hot编码函数\n",
    "import torch # 导入torch库\n",
    "def one_hot_encoding(word, word_to_idx):\n",
    "    # 创建一个全为0的张量，长度与词汇表大小相同\n",
    "    tensor = torch.zeros(len(word_to_idx))  \n",
    "    tensor[word_to_idx[word]] = 1  # 将对应词汇的索引位置置为1\n",
    "    return tensor  # 返回生成的One-Hot向量\n",
    "\n",
    "# 展示One-Hot编码前后的数据\n",
    "word_example = \"Teacher\"\n",
    "print(\"One-Hot编码前的单词：\", word_example)\n",
    "print(\"One-Hot编码后的向量：\", one_hot_encoding(word_example, word_to_idx))\n",
    "\n",
    "# 展示编码后的Skip-Gram数据样例\n",
    "print(\"Skip-Gram数据样例（已编码）：\", [(one_hot_encoding(context, word_to_idx), \n",
    "          word_to_idx[target]) for context, target in skipgram_data[:3]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "31ae5270",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Skip-Gram模型： SkipGram(\n",
      "  (input_to_hidden): Embedding(9, 2)\n",
      "  (hidden_to_output): Linear(in_features=2, out_features=9, bias=False)\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "# 定义Skip-Gram模型\n",
    "import torch.nn as nn # 导入neural network\n",
    "class SkipGram(nn.Module):\n",
    "    def __init__(self, voc_size, embedding_size):\n",
    "        super(SkipGram, self).__init__()\n",
    "        self.input_to_hidden = nn.Embedding(voc_size, embedding_size)\n",
    "        self.hidden_to_output = nn.Linear(embedding_size, voc_size, bias=False)\n",
    "\n",
    "    def forward(self, X):\n",
    "        hidden_layer = self.input_to_hidden(X)  # 生成隐藏层：[batch_size, embedding_size]\n",
    "        output_layer = self.hidden_to_output(hidden_layer)  # 生成输出层：[batch_size, voc_size]\n",
    "        return output_layer\n",
    "   \n",
    "embedding_size = 2 # 设定嵌入层的大小，这里选择2是为了方便展示\n",
    "skipgram_model = SkipGram(voc_size,embedding_size)  # 实例化SkipGram模型\n",
    "print(\"Skip-Gram模型：\", skipgram_model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "311ccd16",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch: 100, Loss: 2.170751627286275\n",
      "Epoch: 200, Loss: 2.141111485163371\n",
      "Epoch: 300, Loss: 2.121605165799459\n",
      "Epoch: 400, Loss: 2.104543395837148\n",
      "Epoch: 500, Loss: 2.0864566961924234\n",
      "Epoch: 600, Loss: 2.0653944611549377\n",
      "Epoch: 700, Loss: 2.0400773763656614\n",
      "Epoch: 800, Loss: 2.009880606333415\n",
      "Epoch: 900, Loss: 1.9752671122550964\n",
      "Epoch: 1000, Loss: 1.938121779759725\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 训练Skip-Gram模型\n",
    "learning_rate = 0.001 # 设置学习速率\n",
    "epochs = 1000 # 设置训练轮次\n",
    "criterion = nn.CrossEntropyLoss()  # 定义交叉熵损失函数\n",
    "import torch.optim as optim # 导入随机梯度下降优化器\n",
    "optimizer = optim.SGD(skipgram_model.parameters(), lr=learning_rate)  \n",
    "\n",
    "# 开始训练循环\n",
    "loss_values = []  # 用于存储每轮的平均损失值\n",
    "for epoch in range(epochs):\n",
    "    loss_sum = 0 # 初始化损失值\n",
    "    for context, target in skipgram_data:\n",
    "        X = torch.tensor([word_to_idx[target]], dtype=torch.long)  # # 输入是中心词\n",
    "        y_true = torch.tensor([word_to_idx[context]], dtype=torch.long)  # 目标词是上下文词 \n",
    "        y_pred = skipgram_model(X)  # 计算预测值\n",
    "        loss = criterion(y_pred, y_true)  # 计算损失\n",
    "        loss_sum += loss.item() # 累积损失\n",
    "        optimizer.zero_grad()  # 清空梯度\n",
    "        loss.backward()  # 反向传播\n",
    "        optimizer.step()  # 更新参数\n",
    "    if (epoch+1) % 100 == 0: # 输出每100轮的损失，并记录损失\n",
    "        print(f\"Epoch: {epoch+1}, Loss: {loss_sum/len(skipgram_data)}\")  \n",
    "        loss_values.append(loss_sum / len(skipgram_data))\n",
    "\n",
    "# 绘制训练损失曲线\n",
    "import matplotlib.pyplot as plt # 导入matplotlib\n",
    "plt.plot(range(1, epochs//100 + 1), loss_values) # 绘图\n",
    "plt.title('Training Loss') # 图题\n",
    "plt.xlabel('Epochs') # X轴Label\n",
    "plt.ylabel('Loss') # Y轴Label\n",
    "plt.show() # 显示图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "75e56ed1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Skip-Gram词嵌入:\n",
      "Boss:     [0.08641931 0.0041279 ]\n",
      "is:     [0.4300888  0.32973588]\n",
      "Niuzong:     [0.97746634 0.9878284 ]\n",
      "Teacher:     [1.287913  0.2388361]\n",
      "Xiaoxue:     [1.4833556 1.2064167]\n",
      "Kage:     [-0.9543879 -1.0170158]\n",
      "Xiaobing:     [-0.5623761   0.68400425]\n",
      "Mazong:     [ 1.6393309  -0.29464877]\n",
      "Student:     [ 1.7798469  -0.48787424]\n"
     ]
    }
   ],
   "source": [
    "# 输出Skip-Gram习得的词嵌入\n",
    "print(\"\\nSkip-Gram词嵌入:\")\n",
    "for word, idx in word_to_idx.items(): # 输出每个单词的嵌入向量\n",
    "    print(f\"{word}: \\\n",
    "    {skipgram_model.input_to_hidden.weight[idx].detach().numpy()}\")  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "a1670078",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "findfont: Font family ['SimHei'] not found. Falling back to DejaVu Sans.\n",
      "/home/huangjia/ENTER/lib/python3.9/site-packages/IPython/core/pylabtools.py:151: UserWarning: Glyph 32500 (\\N{CJK UNIFIED IDEOGRAPH-7EF4}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "/home/huangjia/ENTER/lib/python3.9/site-packages/IPython/core/pylabtools.py:151: UserWarning: Glyph 35789 (\\N{CJK UNIFIED IDEOGRAPH-8BCD}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "/home/huangjia/ENTER/lib/python3.9/site-packages/IPython/core/pylabtools.py:151: UserWarning: Glyph 23884 (\\N{CJK UNIFIED IDEOGRAPH-5D4C}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "/home/huangjia/ENTER/lib/python3.9/site-packages/IPython/core/pylabtools.py:151: UserWarning: Glyph 20837 (\\N{CJK UNIFIED IDEOGRAPH-5165}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "findfont: Font family ['SimHei'] not found. Falling back to DejaVu Sans.\n",
      "/home/huangjia/ENTER/lib/python3.9/site-packages/IPython/core/pylabtools.py:151: UserWarning: Glyph 21521 (\\N{CJK UNIFIED IDEOGRAPH-5411}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "/home/huangjia/ENTER/lib/python3.9/site-packages/IPython/core/pylabtools.py:151: UserWarning: Glyph 37327 (\\N{CJK UNIFIED IDEOGRAPH-91CF}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n",
      "/home/huangjia/ENTER/lib/python3.9/site-packages/IPython/core/pylabtools.py:151: UserWarning: Glyph 24230 (\\N{CJK UNIFIED IDEOGRAPH-5EA6}) missing from current font.\n",
      "  fig.canvas.print_figure(bytes_io, **kw)\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.rcParams[\"font.family\"]=['SimHei'] # 用来设定字体样式\n",
    "plt.rcParams['font.sans-serif']=['SimHei'] # 用来设定无衬线字体样式\n",
    "plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号\n",
    "# 绘制二维词向量图\n",
    "fig, ax = plt.subplots() \n",
    "for word, idx in word_to_idx.items():\n",
    "    vec = skipgram_model.input_to_hidden.weight[\\\n",
    "            idx].detach().numpy() # 获取每个单词的嵌入向量\n",
    "    ax.scatter(vec[0], vec[1]) # 在图中绘制嵌入向量的点\n",
    "    ax.annotate(word, (vec[0], vec[1]), fontsize=12) # 点旁添加单词标签\n",
    "plt.title('2维词嵌入') # 图题\n",
    "plt.xlabel('向量维度1') # X轴Label\n",
    "plt.ylabel('向量维度2') # Y轴Label\n",
    "plt.show() # 显示图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "27c673b0",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
